package taskhandler

import (
	"fmt"
	"strings"

	"k8s.io/apimachinery/pkg/util/sets"

	"cvevulner/common"
	"cvevulner/models"
	"cvevulner/util"

	"github.com/astaxie/beego/logs"
)

var tb = `| 状态  | 分析项目 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`

func CheckIssueAnalysisComplete(i *models.IssueTemplate) (msg, tbStr string, ok bool) {
	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}

	if util.TrimString(i.CveAnalysis) == "" {
		msg = "1.影响性分析说明=> 没有填写或按正确格式填写"
		return
	}

	affectBranchsxList := make([]string, 0)
	owner, accessToken := common.GetOwnerAndToken("", util.Openeuler)
	affectBranchsxList, _ = GetBranchesInfo(accessToken, owner, i.Repo, util.Openeuler)
	if len(affectBranchsxList) == 0 {
		msg = "获取仓库分支信息失败"
		return
	}
	affectBranchSets := sets.New(affectBranchsxList...)

	var affectedResult string
	if i.AffectedVersion != "" {
		checkResult := itemCheck(i.AffectedVersion, affectBranchSets, func(result string) bool {
			return result == "受影响" || result == "不受影响"
		})
		if checkResult != "" {
			msg = fmt.Sprintf("4.受影响版本排查(受影响/不受影响)=> %s", checkResult)
			return
		}

		affectedResult = util.TrimStringNR(i.AffectedVersion)

		if i.OpenEulerVector == "" {
			msg = "2.openEulerVector=> 没有正确填写"
			return
		}

		if i.OpenEulerScore == 0.0 {
			msg = "2.openEulerScore=> 没有填写或正确填写(0-10)"
			return
		}
	}

	if msg = scoreVectorCheck(i); msg != "" {
		return
	}

	var abiResult string
	if i.AbiVersion != "" {
		checkResult := itemCheck(i.AbiVersion, affectBranchSets, func(result string) bool {
			return result == "是" || result == "否"
		})
		if checkResult != "" {
			msg = fmt.Sprintf("5.修复是否涉及abi变化(是/否)=> %s", checkResult)
			return
		}

		abiResult = util.TrimStringNR(i.AbiVersion)
	}

	var analysisReasonResult string
	if i.AnalysisVersion != "" {
		checkResult := itemCheck(i.AnalysisVersion, affectBranchSets, func(result string) bool {
			return common.AnalysisSets.Has(result)
		})
		if checkResult != "" {
			msg = fmt.Sprintf("6.原因说明=> %v", checkResult)
			return
		}

		analysisReasonResult = util.TrimStringNR(i.AnalysisVersion)
	}

	if i.AffectedVersion != "" && i.AnalysisVersion != "" {
		var notMatchBranch []string

		for _, b := range affectBranchsxList {
			getResult := func(item string) string {
				for _, v := range strings.Split(item, ",") {
					row := strings.Split(v, ":")
					if row[0] == b {
						return row[1]
					}
				}

				return ""
			}

			affectR := getResult(i.AffectedVersion)
			analysisR := getResult(i.AnalysisVersion)

			_, exist := common.AnalysisUnaffected[analysisR]
			if (affectR == "不受影响" && !exist) || (affectR == "受影响" && exist) {
				notMatchBranch = append(notMatchBranch, b)
			}
		}

		if len(notMatchBranch) > 0 {
			msg = fmt.Sprintf("受影响/不受影响和原因分析不匹配，分支： %v", notMatchBranch)
			return
		}
	}

	tbStr = fmt.Sprintf(tb,
		"已分析", "1.影响性分析说明", util.TrimStringNR(i.CveAnalysis),
		"已分析", "2.openEulerScore", i.OpenEulerScore,
		"已分析", "3.openEulerVector", util.TrimStringNR(i.OpenEulerVector),
		"已分析", "4.受影响版本排查", affectedResult,
		"已分析", "5.是否涉及abi变化", abiResult,
		"已分析", "6.原因说明", analysisReasonResult,
	)

	ok = true

	return
}

func itemCheck(item string, branchSets sets.Set[string], resultCheck func(result string) bool) string {
	itemBranchSets := make(sets.Set[string])
	for _, v := range strings.Split(item, ",") {
		row := strings.Split(v, ":")
		if len(row) != 2 {
			return fmt.Sprintf("没有分析或未按正确格式填写: %s", v)
		}

		if !resultCheck(row[1]) {
			return fmt.Sprintf("分支 %s 结果填写错误", row[0])
		}

		itemBranchSets.Insert(row[0])
	}

	diff := branchSets.Difference(itemBranchSets)
	if diff.Len() != 0 {
		return fmt.Sprintf("没有分析或未按正确格式填写，涉及分支: %v", diff.UnsortedList())
	}

	return ""
}

func scoreVectorCheck(issueTmp *models.IssueTemplate) string {
	matched, err := util.ScoreAndVectorCheck(issueTmp.OpenEulerScore, issueTmp.OpenEulerVector)
	if err != nil {
		return err.Error()
	}

	if !matched {
		return "CVSS评分和矢量值不一致，请修改至矢量值和CVSS评分一致！"
	}

	return ""
}

func CheckOtherIssueAnalysisComplete(i *models.IssueTemplate, organizationID int8) (msg, tbStr string, ok bool) {
	tb :=
		`| 状态  | 需分析 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`
	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}
	var score, vector string
	switch organizationID {
	case util.OpenLookeng:
		score = "openLooKengScore"
		vector = "openLooKengVector"
	case util.OpenGauss:
		score = "openGaussScore"
		vector = "openGaussVector"
	case util.MindSpore:
		score = "MindSporeScore"
		vector = "MindSporeVector"
	}
	ok = true
	tbContent := make([]interface{}, 12)
	if util.TrimString(i.CveAnalysis) == "" || len(util.TrimString(i.CveAnalysis)) < 1 {
		msg = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		ok = false
		return
	}
	tbContent[0] = "已分析"
	tbContent[1] = "1.影响性分析说明"
	tbContent[2] = util.TrimStringNR(i.CveAnalysis)
	affectedVersionFlag := 1
	if i.AffectedVersion != "" {
		versionfFlag := true
		affectedVersionArry := strings.Split(i.AffectedVersion, ",")
		if len(affectedVersionArry) > 0 {
			for _, affect := range affectedVersionArry {
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "受影响" || versionArry[1] == "不受影响" {
						if versionArry[1] == "受影响" {
							affectedVersionFlag = 2
						}
						continue
					} else {
						affectedVersionFlag = 3
						versionfFlag = false
						break
					}
				} else {
					affectedVersionFlag = 3
					versionfFlag = false
					break
				}
			}
		}
		if !versionfFlag {
			msg = fmt.Sprintf("4.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			ok = false
			return
		}
		if versionfFlag {
			tbContent[9] = "已分析"
			tbContent[10] = "4.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		} else {
			tbContent[9] = "待分析"
			tbContent[10] = "4.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		}
	} else {
		tbContent[9] = "已分析"
		tbContent[10] = "4.受影响版本排查"
		tbContent[11] = ""
	}
	if affectedVersionFlag == 1 {
		tbContent[3] = "已分析"
		tbContent[4] = "2." + score
		tbContent[5] = i.OpenEulerScore
		tbContent[6] = "已分析"
		tbContent[7] = "3." + vector
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	} else {
		if organizationID != util.OpenGauss && i.OpenEulerScore == 0.0 {
			msg = fmt.Sprintf("2.%s=> 没有填写或正确填写(0-10)", score)
			ok = false
			return
		}
		tbContent[3] = "已分析"
		tbContent[4] = "2." + score
		tbContent[5] = i.OpenEulerScore
		if i.OpenEulerVector == "" || len(i.OpenEulerVector) < 1 {
			msg = fmt.Sprintf("3.%s=> 没有正确填写", vector)
			ok = false
			return
		}
		tbContent[6] = "已分析"
		tbContent[7] = "3." + vector
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	}
	tbStr = fmt.Sprintf(tb, tbContent...)
	return
}

func CheckIssueClosedAnalysisComplete(i *models.IssueTemplate) (msg, tbStr string, ok bool) {
	tb :=
		`| 状态  | 需分析 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`
	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}
	ok = true
	tbContent := make([]interface{}, 15)
	if util.TrimString(i.CveAnalysis) == "" || len(util.TrimString(i.CveAnalysis)) < 2 {
		tbContent[0] = "待分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		msg = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		ok = false
	} else {
		tbContent[0] = "已分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = util.TrimStringNR(i.CveAnalysis)
	}
	affectedVersionFlag := 1
	if i.AffectedVersion != "" {
		versionfFlag := true
		affectedVersionArry := strings.Split(i.AffectedVersion, ",")
		if len(affectedVersionArry) > 0 {
			for _, affectx := range affectedVersionArry {
				affect := common.BranchVersionRep(affectx)
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "受影响" || versionArry[1] == "不受影响" {
						if versionArry[1] == "受影响" {
							affectedVersionFlag = 2
						}
						continue
					} else {
						affectedVersionFlag = 3
						versionfFlag = false
						break
					}
				} else {
					affectedVersionFlag = 3
					versionfFlag = false
					break
				}
			}
		}
		if !versionfFlag {
			tbContent[9] = "待分析"
			tbContent[10] = "4.受影响版本排查"
			tbContent[11] = fmt.Sprintf("4.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			msg = fmt.Sprintf("4.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			ok = false
		} else {
			tbContent[9] = "已分析"
			tbContent[10] = "4.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		}
	} else {
		tbContent[9] = "已分析"
		tbContent[10] = "4.受影响版本排查"
		tbContent[11] = ""
	}
	if affectedVersionFlag == 1 {
		tbContent[3] = "已分析"
		tbContent[4] = "2.openEulerScore"
		tbContent[5] = i.OpenEulerScore
		tbContent[6] = "已分析"
		tbContent[7] = "3.openEulerVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	} else {
		if i.OpenEulerScore == 0.0 {
			tbContent[3] = "待分析"
			tbContent[4] = "2.openEulerScore"
			tbContent[5] = fmt.Sprintf("2.openEulerScore=> 没有填写或正确填写(0-10)")
			msg = fmt.Sprintf("2.openEulerScore=> 没有填写或正确填写(0-10)")
			ok = false
		} else {
			tbContent[3] = "已分析"
			tbContent[4] = "2.openEulerScore"
			tbContent[5] = i.OpenEulerScore
		}
		if util.TrimString(i.OpenEulerVector) == "" || len(util.TrimString(i.OpenEulerVector)) < 1 {
			tbContent[6] = "待分析"
			tbContent[7] = "3.openEulerVector"
			tbContent[8] = fmt.Sprintf("3.openEulerVector=> 没有正确填写")
			msg = fmt.Sprintf("3.openEulerVector=> 没有正确填写")
			ok = false
		} else {
			tbContent[6] = "已分析"
			tbContent[7] = "3.openEulerVector"
			tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
		}
	}
	if i.AbiVersion != "" {
		versionAbiFlag := true
		abiVersionArry := strings.Split(i.AbiVersion, ",")
		if len(abiVersionArry) > 0 {
			for _, affectx := range abiVersionArry {
				affect := common.BranchVersionRep(affectx)
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "是" || versionArry[1] == "否" {
						continue
					} else {
						versionAbiFlag = false
						break
					}
				} else {
					versionAbiFlag = false
					break
				}
			}
		}
		if !versionAbiFlag {
			tbContent[12] = "待分析"
			tbContent[13] = "5.修复是否涉及abi变化"
			tbContent[14] = fmt.Sprintf("5.修复是否涉及abi变化(是/否)=> 没有分析或未按正确格式填写:%v", i.AbiVersion)
			msg = fmt.Sprintf("5.修复是否涉及abi变化(是/否)=> 没有分析或未按正确格式填写:%v", i.AbiVersion)
			ok = false
		} else {
			tbContent[12] = "已分析"
			tbContent[13] = "5.修复是否涉及abi变化"
			tbContent[14] = util.TrimStringNR(i.AbiVersion)
		}
	} else {
		tbContent[12] = "已分析"
		tbContent[13] = "5.修复是否涉及abi变化"
		tbContent[14] = ""
	}
	tbStr = fmt.Sprintf(tb, tbContent...)
	return
}

func CheckOtherIssueClosedAnalysisComplete(i *models.IssueTemplate, v *models.VulnCenter) (msg, tbStr string, ok bool) {
	tb :=
		`| 状态  | 需分析 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`
	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}
	var score, vector string
	switch v.OrganizationID {
	case util.OpenLookeng:
		score = "openLooKengScore"
		vector = "openLooKengVector"
	case util.OpenGauss:
		score = "openGaussScore"
		vector = "openGaussVector"
	case util.MindSpore:
		score = "MindSporeScore"
		vector = "MindSporeVector"
	}
	ok = true
	tbContent := make([]interface{}, 12)
	if util.TrimString(i.CveAnalysis) == "" || len(util.TrimString(i.CveAnalysis)) < 2 {
		tbContent[0] = "待分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		msg = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		ok = false
	} else {
		tbContent[0] = "已分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = util.TrimStringNR(i.CveAnalysis)
	}
	affectedVersionFlag := 1
	if i.AffectedVersion != "" {
		versionfFlag := true
		affectedVersionArry := strings.Split(i.AffectedVersion, ",")
		if len(affectedVersionArry) > 0 {
			for _, affect := range affectedVersionArry {
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "受影响" || versionArry[1] == "不受影响" {
						if versionArry[1] == "受影响" {
							affectedVersionFlag = 2
						}
						continue
					} else {
						affectedVersionFlag = 3
						versionfFlag = false
						break
					}
				} else {
					affectedVersionFlag = 3
					versionfFlag = false
					break
				}
			}
		}
		if !versionfFlag {
			tbContent[9] = "待分析"
			tbContent[10] = "4.受影响版本排查"
			tbContent[11] = fmt.Sprintf("4.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			msg = fmt.Sprintf("4.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			ok = false
		} else {
			tbContent[9] = "已分析"
			tbContent[10] = "4.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		}
	} else {
		tbContent[9] = "已分析"
		tbContent[10] = "4.受影响版本排查"
		tbContent[11] = ""
	}
	if affectedVersionFlag == 1 {
		tbContent[3] = "已分析"
		tbContent[4] = "2." + score
		tbContent[5] = i.OpenEulerScore
		tbContent[6] = "已分析"
		tbContent[7] = "3." + vector
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	} else {
		if v.OrganizationID != util.OpenGauss && i.OpenEulerScore == 0.0 {
			tbContent[3] = "待分析"
			tbContent[4] = "2." + score
			tbContent[5] = fmt.Sprintf("2.%s=> 没有填写或正确填写(0-10)", score)
			msg = fmt.Sprintf("2.%s=> 没有填写或正确填写(0-10)", score)
			ok = false
		} else {
			tbContent[3] = "已分析"
			tbContent[4] = "2." + score
			tbContent[5] = i.OpenEulerScore
		}
		if util.TrimString(i.OpenEulerVector) == "" || len(util.TrimString(i.OpenEulerVector)) < 1 {
			tbContent[6] = "待分析"
			tbContent[7] = "3." + vector
			tbContent[8] = fmt.Sprintf("3.%s=> 没有正确填写", vector)
			msg = fmt.Sprintf("3.%s=> 没有正确填写", vector)
			ok = false
		} else {
			tbContent[6] = "已分析"
			tbContent[7] = "3." + vector
			tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
		}
	}
	tbStr = fmt.Sprintf(tb, tbContent...)
	return
}
